/***
 * rmh 2021/09/15
 * 表格中输入框方向键切换, 仅仅适用于 el-table
 */

import Vue from 'vue';

Vue.directive('tableMove', {
  bind(el, binding, vnode) {
    vnode.context.$nextTick(() => {
      const inputEls = el.querySelectorAll('.el-input input');
      if (inputEls && inputEls.length) {
        for (let i = 0; i < inputEls.length; i++) {
          inputEls[i].addEventListener('keyup', listenInputKeyup, false);
        }
      }
    })
  },
  componentUpdated(el, binding, vnode, oldVnode) {
    const oldEls = oldVnode.elm.querySelectorAll('.el-input input');
    if (oldEls && oldEls.length) {
      for (let i = 0; i < oldEls.length; i++) {
        oldEls[i].removeEventListener('keyup', listenInputKeyup, false);
      }
    }
    
    vnode.context.$nextTick(() => {
      const inputEls = el.querySelectorAll('.el-input input');
      if (inputEls && inputEls.length) {
        for (let i = 0; i < inputEls.length; i++) {
          inputEls[i].addEventListener('keyup', listenInputKeyup, false);
        }
      }
    })
  }
});

// 监听输入框的键盘事件
function listenInputKeyup(evt) {
  evt.preventDefault && evt.preventDefault();
  let range = evt.target.selectionStart, valStr = evt.target.value;  // 当前输入框的光标位置 当前输入框的内容
  let parentTd = queryParentNodByElName(evt.target, 'td');  // 当前输入框的父级表格td
  let cellIndex = parentTd.cellIndex, rowIndex = parentTd.parentElement.sectionRowIndex;  // 当前输入框对应表格的位置
  let tbodyEl = parentTd.parentElement.parentElement.children;  // 当前input所在表格body元素
  let rIndex = -1, cIndex = -1, tdEls = [], tdLen = -1, inputEl = null;

  switch(evt.keyCode) {
    case 38:  // 上键
      if (rowIndex < 1) return false; // 如果是第一行, 上键失效
      cIndex = cellIndex;
      tdEls = tbodyEl[rowIndex - 1].children;
      tdLen = tdEls.length - 1;
      inputEl = tdEls[cIndex].querySelector('.el-input') || null;

      while(!inputEl && cIndex > -1 && cIndex < tdLen) {
        if (cIndex <= cellIndex) {
          if (cIndex <= 1) {
            cIndex = cellIndex + 1;
          } else {
            cIndex --;
          }
        } else {
          cIndex ++;
        }

        inputEl = tdEls[cIndex].querySelector('.el-input') || null;
      }
      break;
    case 37:  // 左键
      if (range > 0) return false;    // input的光标不在文字首位, 不进行切换
      if (cellIndex < 1 && rowIndex < 1) return false;  // input位置在第一行的第一个单元格中, 不进行切换
      rIndex = rowIndex;
      cIndex = cellIndex - 1;
      tdEls = tbodyEl[rIndex].children;
      inputEl = tdEls[cIndex].querySelector('.el-input') || null;

      while(!inputEl && rIndex > -1 && cIndex >= 0) {
        if (cIndex === 0 && rIndex > 0) {
          rIndex-=1;
          tdEls = tbodyEl[rIndex].children;
          cIndex = tdEls.length;
        }
        cIndex--;
        if (cIndex > -1) inputEl = tdEls[cIndex].querySelector('.el-input') || null;
      }
      break;
    case 39:  // 右键
      if (range < (valStr.length - 1)) return false;  // input的光标不在字符串末尾, 不进行切换
      tdEls = tbodyEl[rowIndex].children;
      if ((tdEls.length - 1) <= cellIndex && (tbodyEl.length - 1) <= rowIndex) return false; // input在最后一行最后一个单元格
      cIndex = cellIndex + 1;
      rIndex = rowIndex;
      tdLen = tdEls.length - 1
      let trLen = tbodyEl.length - 1;
      inputEl = tdEls[cIndex].querySelector('.el-input') || null;

      while(!inputEl && trLen >= rIndex && tdLen >= cIndex) {
        if (cIndex >= tdLen && trLen > rIndex) {
          cIndex = -1;
          rIndex++;
          tdEls = tbodyEl[rIndex].children;
          tdLen = tdEls.length - 1;
        }
        cIndex++;
        if(tdLen >= cIndex) inputEl = tdEls[cIndex].querySelector('.el-input') || null;
      }
      break;
    case 40:  // 下键
      if (rowIndex >= (tbodyEl.length - 1)) return false; // 当前位于最后一行, 不进行切换
      rIndex = rowIndex + 1;
      cIndex = cellIndex;
      tdEls = tbodyEl[rIndex].children;
      tdLen = tdEls.length - 1;
      inputEl = tdEls[cIndex].querySelector('.el-input') || null;

      while(!inputEl && cIndex > 0 && cIndex < tdLen) {
        if (cIndex <= cellIndex) {
          if (cIndex <= 1) {
            cIndex = cellIndex + 1;
          }
          cIndex--;
        } else {
          cIndex++;
        }
        inputEl = tdEls[cIndex].querySelector('.el-input') || null;
      }
      break;
    default: return;
  }
  tdEls[cIndex] && tdEls[cIndex].focus();
  inputEl && inputEl.querySelector('input').focus();
}

// 获取自定元素的父级元素
function queryParentNodByElName(el, elName) {
  if (!el) return;
  if (!elName) return el.parentNode || null;

  while(el && el.nodeName.toLowerCase() !== elName.toLowerCase()) {
    el = el.parentNode || null;
  }
  return el;
}
